package app.controller.msgmanage;

import app.schedule.SpringApplicationContextHolder;
import app.service.DeviceManageService;
import app.service.FacilitiesManageService;
import app.service.UserManageService;
import com.mess.warningmess.WarningMass;
import refactor.entity.Device;
import siotwx.entity.Eventlog;
import siotwx.entity.Facilities;
import siotwx.entity.Facmonitoring;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 这个类用于被调用用来传输特定时间之前转发失败过的数据，用来重新转发
 * @author 昊琦
 * @创建时间 2018年3月19日16:53:59
 */
public class MsgManageSupportAgain {

	
	private DeviceManageService dms = (DeviceManageService) SpringApplicationContextHolder.context.getBean("DeviceManageService");

	private FacilitiesManageService fms=(FacilitiesManageService) SpringApplicationContextHolder.context.getBean("FacilitiesManageService");
	
	private UserManageService ums=(UserManageService) SpringApplicationContextHolder.context.getBean("UserManageService");

	
	/**
	 * 对应 上行 控制类型98，硬件主动上报故障信息的处理
	 * @param msgArray
	 * @param d_time
	 * @return
	 */
	public  String faultHandle(String[] msgArray,long d_time){
		
		//设备编码
		String devCode = msgArray[0];
		//控制类型
		String controlCode = msgArray[1];
		//故障类型
		String faultType = msgArray[2];
		
		
		//判断设备是否被绑定
		Device device= dms.toDecideBind(devCode);
		if (device!=null) {
			//如果设备有效，则把故障信息录入数据库
			Facilities fac = fms.get(device.getFacilitiesId());
			

			
			dms.saveDevFault(device, fac, Integer.valueOf(faultType), d_time);
		
		}

		//返回服务器响应
		
		String rep = "("+devCode+")";
		return rep;
	}
	
	/**
	 * 对应 上行 控制类型51  硬件响应服务器读取心跳参数
	 * @param msgArray
	 * @param d_time
	 */
	public  void heartbeatHandle(String[] msgArray,long d_time){
		//设备编码
		String devCode = msgArray[0];
		//控制类型码
		String controlCode = msgArray[1];
		
		String tempStr = msgArray[2];
		
		String tempArray[] = tempStr.split("-");
		//心跳间隔
		String span = tempArray[0];
		
		
		/*具体操作容后再做
		 * 
		 */

	}
	
	/**
	 * 对应 上行 控制类型码53  硬件响应服务器设置心跳参数
	 * @param msgArray
	 * @param d_time
	 */
	public  void  deviceRespondToChangeHeartbeat(String[] msgArray,long d_time){
		
		//设备编码
		String devCode = msgArray[0];
		//控制类型码
		String controlCode = msgArray[1];
		
		String tempStr = msgArray[2];
		
		String tempArray[] = tempStr.split("-");
		//心跳间隔
		String span = tempArray[0];
		
		/*相应入库操作，等数据库修改后来做
		 * 
		 * 
		 * 
		 */
		
		
	}
	
	/**
	 * 对应 上行 控制类型码55  硬件响应服务器读取等待用户开锁时间参数
	 * @param msgArray
	 * @param d_time
	 */
	public  void deviceRespondToServerRequestLockTime(String[] msgArray,long d_time){
		//设备编码
		String devCode = msgArray[0];
		//控制类型码
		String controlCode = msgArray[1];
		//开锁时间间隔
		String lockTime = msgArray[2];
		
		/*
		 * 具体操作先放一放
		 * 
		 * 
		 */
	}
	
	/**
	 * 对应 上行 控制类型码57 硬件响应服务器设置等待用户开锁时间参数 
	 * @param msgArray
	 * @param d_time
	 */
	public  void deviceRespondToServerSetLockTime(String[] msgArray,long d_time){
		
		//设备编码
		String devCode = msgArray[0];
		//控制类型码
		String controlCode = msgArray[1];
		//开锁时间间隔
		String lockTime = msgArray[2];
		
		/*
		 * 具体操作先放一放
		 * 
		 * 
		 */
	}
	
	/**
	 * 对应 上行 控制类型码59  硬件响应服务器读取等待用户开门时间参数
	 * @param msgArray
	 * @param d_time
	 */
	public  void deviceRespondToServerRequestDoorTime(String[] msgArray,long d_time){
		//设备编码
		String devCode = msgArray[0];
		//控制类型码
		String controlCode = msgArray[1];
		//开锁时间间隔
		String lockTime = msgArray[2];
		
		/*
		 * 具体操作先放一放
		 * 
		 * 
		 */
	}
	
	/**
	 * 对应 上行 控制类型码61 硬件响应服务器设置等待用户开门时间参数 
	 * @param msgArray
	 * @param d_time
	 */
	public  void deviceRespondToServerSetDoorTime(String[] msgArray,long d_time){
		
		//设备编码
		String devCode = msgArray[0];
		//控制类型码
		String controlCode = msgArray[1];
		//开锁时间间隔
		String lockTime = msgArray[2];
		
		/*
		 * 具体操作先放一放
		 * 
		 * 
		 */
	}
	
	/**
	 * 对应 上行 控制类型码63  硬件响应服务器设置服务器地址及端口
	 * @param msgArray
	 * @param d_time
	 */
	public void deviceRespondToChangeIp(String[] msgArray,long d_time){
		
		//设备编码
		String devCode=msgArray[0];
		//控制类型码
		String controlCode =msgArray[1];
		//IP地址
		String ipAddress = msgArray[2];
		//端口号
		String port = msgArray[3];
		
		/*具体操作容后再做
		 * 
		 * */
		
		
	}
	
	/**
	 * 对应 上行 控制类型码64  硬件向备用服务器主动报告与主服务器通信异常
	 * @param msgArray
	 * @param d_time
	 */
	public void deviceReportCommunicationsError(String[] msgArray,long d_time){
		//设备编码
		String devCode=msgArray[0];
		//控制类型码
		String controlCode =msgArray[1];
		//IP地址
		String ipAddress = msgArray[2];
		
		String[] tempArray = msgArray[3].split("_");
		//端口
		String port = tempArray[0];
		//信号强度
		String signalIntensity = tempArray[1];
		
		/*具体操作容后再做
		 * 
		 * */

	}
	
	/**
	 * 对应 上行 控制类型码00  硬件主动上报心跳 
	 * @param msgArray
	 * @param d_time
	 * @return
	 */
	public  void receiveHeartbeat(String[] msgArray,long d_time){
		
		//设备编码
		String devCode = msgArray[0];
		//控制类型码
		String controlCode = msgArray[1];
		String tempMsg ="";
		//信息体
		if (msgArray.length>2) {
			 tempMsg=msgArray[2];
		}
		
		
		//获取设备类型
		String devType = devCode.substring(0, 1);
		
		//如果是地井设备
		if (devType.equals("W")) {
			String[] tempArray = tempMsg.split("_");
			//井盖状态，发来的数据中1表示井盖打开，0表示井盖关闭。
			String status = tempArray[0];
			//信号强度
			String signalIntensity =  tempArray[1];
			//收到字符串的时间
			String tempTime = tempArray[2];
			

			long timeNow = formatTime(tempTime);
			
			
			/*
			 * 具体操作容后再做
			 * 
			 */
	
		}
		//如果是通断电设备
		if (devType.equals("E")) {
			
			String[] tempArray = tempMsg.split("_");
			
			//通断电状态，接收到的数据里，1表示有电，0表示没电
			String status = tempArray[0];
			//信号强度
			String signalIntensity =tempArray[1];
			//收到的字符串时间
			String tempTime = tempArray[2];
			
			//转成long型
			long timeNow = formatTime(tempTime);
			
			
			/*具体操作容后来做
			 * 
			 * 
			 * 
			 */
			
		}
		//如果是机柜锁控
		if (devType.equals("L")) {
			String[] tempArray = tempMsg.split("-");
			
			//控锁状态
			String intention = tempArray[0];
			//锁状态
			String lockStu = tempArray[1];
			//门状态
			String doorStu = tempArray[2];
			//电量
			String battery = tempArray[3];
			
			//信号强度和时间
			String[] tempArray2 = tempArray[4].split("_");
			//信号强度
			String signalIntensity = tempArray2[0];
			//收到的时间字符串
			String tempTime = tempArray2[1];
			
			//转成long型
			long timeNow = formatTime(tempTime);
			
			/*具体操作容后来做
			 * 
			 * 
			 * 
			 */
			
			
		}
		//如果是机房锁控
		if (devType.equals("D")) {
			
			String[] tempArray =tempMsg.split("_");
			
			//信号强度
			String signalIntensity = tempArray[0];
			//收到的时间字符串
			String tempTime = tempArray[1];
			
			//转成long型
			long timeNow = formatTime(tempTime);
			
			/*具体操作容后来做
			 * 
			 * 
			 * */
		}
		
	
	}
	
	
	/**
	 * 对应 上行 控制类型代码04  地井硬件主动上报地井井盖状态变化信息
	 * @param msgArray
	 * @param d_time
	 * @return
	 */
//	public  String coverReportStu(String[] msgArray,long d_time){
//		//设备编码
//		String devCode = msgArray[0];
//		//控制类型码
//		String controlCode = msgArray[1];
//		//信息体
//		String tempMsg = msgArray[2];
//		
//		String[] tempArray = tempMsg.split("-");
//		//当前状态
//		String triggerStu = tempArray[0];
//		//变化次数
//		String changeTimes = tempArray[1];
//		//检测到状态变化时的状态
//		String lastStu =tempArray[2];
//		//时间和信号强度
//		String tempMsg2 = tempArray[3];
//		
//		String[] tempArray2 = tempMsg2.split("_");
//		
//		//最新状态的时间 
//		String tempTime = tempArray2[2];
//		//信号强度
//		String signalIntensity =tempArray2[1];
//		
//		//转成long型
//		long timeNow = formatTime(tempTime);
//		
//		String tempStu="";
//		if (triggerStu.equals("1")) {
//			tempStu = "0";
//		}else{
//			tempStu = "1";
//		}
//
//		DatabaseUtils databaseUtils = new DatabaseUtils();
//		//判断设备是否被绑定，以及设施的工作状态有效
//		Device device = databaseUtils.ToDecideBind(devCode);
//		if (device!=null) {
//				//将这条井盖状态变化信息录入数据库，前提是将对应的所有旧信息flag置0
//				Map<Object, Object> param = new HashMap<>();
//				param.put(Eventlog.FieldName.mod_id, device.getMod_id());
//				param.put(Eventlog.FieldName.device_id, device.getId());
//				param.put(Eventlog.FieldName.facilities_id, device.getFacilitiesId());
//				param.put(Eventlog.FieldName.type_id, 2);
//				param.put(Eventlog.FieldName.flag, "1");
//				
//				List<Eventlog> eventlogs = null;
//				
//				try {
//					eventlogs = eventlogService.getList(param);
//				} catch (Exception e) {
//					System.out.println("获取井盖历史记录出错！");
//				}
//				
//				if (eventlogs!=null&&!eventlogs.isEmpty()) {
//					for(int index=0;index<eventlogs.size();index++){
//						Eventlog eventlog = eventlogs.get(index);
//						eventlog.setFlag("0");
//						eventlogService.update(eventlog);
//					}
//				}
//				
//				//添加记录
//				Eventlog eventlog = new Eventlog(null, device.getMod_id(), device.getId(), device.getFacilitiesId(), 0, 0, 2, tempStu, "", "", "", timeNow, 0L, "", "1");
//				eventlogService.save(eventlog);
//
//				//获取设备类型设施名称和相关人员信息
//				String oc="";
//				if (triggerStu.equals("1")) {
//					oc="打开";
//				}else{
//					oc="关闭";
//				}
//				
//				Module module = moduleService.get(device.getMod_id());
//				Facilities facilities = fService.get(device.getFacilitiesId());
//				User user = userService.get(facilities.getUser_id());
//				//发送短信
//				Bean4WarnMessInfo info = new Bean4WarnMessInfo(devCode, module.getName(), facilities.getDescription(), "", user.getRealName(), user.getPhoneNumber(), oc);
		//		WarningMass.sendMess(info);
//		
//		}
//		
//		String resp = "("+devCode+")";
//		
//		return resp;
//		
//	}
	
	/**
	 * 对应 上行 控制类型码06 通断电设备主动上报通断电状态信息，地井设备主动上报井盖状态变化信息
	 * @param msgArray
	 * @param d_time
	 * @return
	 */
	public  void onoffDeviceReportStu(String[] msgArray,long d_time){
		//通断电和地井设备编码
		String devCode = msgArray[0];
		
		//根据设备类型进入不同处理
		if(devCode.substring(0,1).equals("E")){
			//控制类型码
			String controlCode =msgArray[1];
			//信息体
			String status = msgArray[2];

			String[] tempArray = status.split("-");
			//当前是否有电
			String stu1= tempArray[0];
			//检测到变化了几次
			String times = tempArray[1];
			//检测到状态变化时的状态
			String stu2 = tempArray[2];
			
			String[] tempArray2 = tempArray[3].split("_");
			//检测状态变化到的时间
			String time1 = tempArray2[0];
			//信号强度
			String strength = tempArray2[1];
			//发送时的时间
			String time2 = tempArray2[2];
			
			
			long timeNow = formatTime(time2);

			
			//判断设备是否被绑定，并且对应设施的工作状态是否有效
			Device device = dms.toDecideBind(devCode);
			if (device!=null) {		
				
				//添加记录
				dms.saveDevStu(device, 0, stu1, "","", timeNow, "0");
			
			}
			
		}else if(devCode.substring(0,1).equals("W")){
			//如果是地井设备
			
			//控制类型码
			String controlCode = msgArray[1];
			//信息体
			String tempMsg = msgArray[2];
			
			String[] tempArray = tempMsg.split("-");
			//当前状态
			String triggerStu = tempArray[0];
			//变化次数
			String changeTimes = tempArray[1];
			//检测到状态变化时的状态
			String lastStu =tempArray[2];
			//时间和信号强度
			String tempMsg2 = tempArray[3];
			
			String[] tempArray2 = tempMsg2.split("_");
			
			//最新状态的时间 
			String tempTime = tempArray2[2];
			//信号强度
			String signalIntensity =tempArray2[1];
			
			//转成long型
			long timeNow = formatTime(tempTime);
			
			String tempStu="";
			if (triggerStu.equals("1")) {
				tempStu = "0";
			}else{
				tempStu = "1";
			}

			//判断设备是否被绑定，以及设施的工作状态有效
			Device device = dms.toDecideBind(devCode);
			if (device!=null) {
					
					//添加记录
					dms.saveDevStu(device, 0, tempStu, "","", timeNow, "0");
			}
			
		}

	}
	
	
	/**
	 * 对应上行 控制类型码 09 硬件响应完成机房开门
	 * @param msgArray
	 * @param d_time
	 */
	public  void deviceRespondToFinishOpenDoor(String[] msgArray,long d_time){
		//通断电设备编码
		String devCode = msgArray[0];
		//控制类型码
		String controlCode =msgArray[1];
		
		//状态信号强度和时间
		String[] tempArray = msgArray[2].split("_");
		//门状态
		String status = tempArray[0];
		//信号强度
		String signalIntensity = tempArray[1];
		//时间字符串
		String tempTime=tempArray[2];
		
		//转成long型
		long timeNow = formatTime(tempTime);
		
		
		String tempStu ="";
		if (status.equals("O")) {
			tempStu="0";
		}else{
			tempStu = "1";
		}
		
		//根据设备code查询设备是否绑定，如果绑定查询设施工作状态是否有效
		Device device = dms.toDecideBind(devCode);
		if (device!=null) {
			
				//将数据库中对应相关信息flag设为0，并且将此条信息录入数据库
				//添加记录
				dms.saveDevStu(device, 0, "", tempStu,"",timeNow, "0");			
		}
	
	}
	
	/**
	 * 对应 上行 控制类型码10 机柜锁硬件主动上报电量信息
	 * @param msgArray
	 * @param d_time
	 * @return
	 */
	public  void lockReportElectricQuantity(String[] msgArray,long d_time){
		//设备编码
		String devCode = msgArray[0];
		//控制类型码
		String controlCode = msgArray[1];
		//信息体
		String tempMsg = msgArray[2];
		
		String[] tempArray = tempMsg.split("-");
		//控锁状态
		String intention = tempArray[0];
		//锁状态
		String lockStu = tempArray[1];
		
		
		
		String templockStu ="";
		if (lockStu.equals("O")) {
			templockStu="0";
		}else{
			templockStu="1";
		}
		//门状态
		String doorStu = tempArray[2];
		String tempdoorStu ="";
		if (doorStu.equals("O")) {
			tempdoorStu="0";
		}else{
			tempdoorStu="1";
		}
		
		//剩余电量
		String battery = tempArray[3];
		
		//信号强度和时间
		String tempMsg2 = tempArray[4];
		
		String[] tempArray2 = tempMsg2.split("_");
		//信号强度
		String signalIntensity=tempArray2[0];
		//收到的时间字符串
		String tempTime=tempArray2[1];
		

		//转成long型
		long timeNow = formatTime(tempTime);
		
		
		//从Facmonitoring中查找对应devCode的记录
		Map<Object, Object> param = new HashMap<>();
		param.put(Facmonitoring.FieldName.devCode,devCode);
		
		Facmonitoring facmonitoring = fms.getFacmonitoring(devCode);
		
		if (facmonitoring!=null) {
			
			//获取对应的eventlogId,修改此eventlog记录的信息
			int eventlogId = facmonitoring.getEventId();
			
			Eventlog eventlog = fms.getEvent(eventlogId);
			

			fms.updateDevstuDoorstuElectricity(eventlog, templockStu, tempdoorStu, battery);
		}
		

		
	}
	
	/**
	 * 对应 上行  控制类型码12 硬件主动上报机柜锁按键触发开门请求
	 * @param msgArray
	 * @param d_time
	 * @return
	 */
	public  void lockDeviceRequestOpenDoor(String[] msgArray,long d_time){
		//设备编码
		String devCode = msgArray[0];
		//控制类型码
		String controlCode = msgArray[1];
		

	}
	
	/**
	 * 对应上行 控制类型码14 硬件主动上报机柜锁和门状态发生变化
	 * @param msgArray
	 * @param d_time
	 * @return
	 */
	public  void lockDeviceReportLockAndDoorStu(String[] msgArray,long d_time){
		//设备编码
		String devCode=msgArray[0];
		//控制类型码
		String controlCode = msgArray[1];
		//信息体
		String tempMsg = msgArray[2];
		
		String[] tempArray = tempMsg.split("_");
		
		//锁信息
		String lockMsg = tempArray[0];
		String[] templockMsg = lockMsg.split("-");
		String lockStu = templockMsg[0];
		String templockStu ="";
		if (lockStu.equals("O")) {
			templockStu = "0";
		}else{
			templockStu="1";
		}
		
		//门信息、电量和信号强度
		String doorMsg = tempArray[1];
		String[] tempdoorMsg = doorMsg.split("-");
		String doorStu = tempdoorMsg[0];
		String tempdoorStu = "";
		if (doorStu.equals("O")) {
			tempdoorStu="0";
		}else{
			tempdoorStu="1";
		}
		
		//电量信息
		String battery = tempdoorMsg[3];
		//信号强度
		String signalIntensity = tempdoorMsg[4];
		
		
		//时间字符串
		String tempTime = tempArray[2];
		

		//转成long型
		long timeNow = formatTime(tempTime);
		
		
		
		//查询设备是否被绑定,如果被绑定则判断设备设施的工作状态是否正常

		Device device = dms.toDecideBind(devCode);
		
		if (device!=null) {
				
				//添加记录
				dms.saveDevStu(device, 0, templockStu, tempdoorStu,battery, timeNow, "0");
		}

	}
	
	
	/**
	 * 对应上行 控制类型码16 用户未执行开门，硬件主动上报
	 * @param msgArray
	 * @param d_time
	 * @return
	 */
	public  void deviceReportUserNotOpenDoor(String[] msgArray,long d_time){
		//设备编码
		String devCode = msgArray[0];
		//设备控制类型码
		String controlCode = msgArray[1];
		
		//说明用户扫了码但是没有按按钮，因此将从存放开门状态的单例缓存中删除此条开门请求对应信息
		DeviceCache deviceCache = DeviceCache.getInstance();
		
			deviceCache.del(devCode);

	}
	
	
	/**
	 * 格式化时间，转成long型
	 * @param tempTime
	 * @return
	 */
	private long formatTime(String tempTime){
		
		SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmss");
		Date date=null;
		try {
			date = sdf.parse(tempTime);
		} catch (ParseException e1) {
			System.out.println("时间转化失败！");
		}
		//转成long型
		long timeNow = date.getTime();
		
		
		return timeNow;
	}
	
	

}
